package com.bywlkjs.bygo.wechat.applet.entity;

import com.alibaba.fastjson.JSON;
import com.bywlkjs.bygo.wechat.applet.config.WechatAppletConfig;
import com.bywlkjs.bygo.wechat.applet.entity.ex.AppletUserInfoEntityException;
import com.bywlkjs.common.util.AesCbcUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

public class AppletUserInfoEntity {

    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Param {
        private String code;
        private String encryptedData;
        private String iv;
    }

    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public static class UserInfoResult {
        private String openId;
        private String nickname;
        private Integer gender;
        private String city;
        private String province;
        private String country;
        private String avatarUrl;
        private String unionid;
        private Integer errcode;
        private Integer errmsg;

        private WechatAppletConfig wechatAppletConfig;

        public UserInfoResult analysis(Param param){
            UserInfoResult decrypt = AppletUserInfoEntity.decrypt(wechatAppletConfig, param, UserInfoResult.class);
            this.setUnionid(decrypt.getUnionid())
                    .setProvince(decrypt.getProvince())
                    .setOpenId(decrypt.getOpenId())
                    .setNickname(decrypt.getNickname())
                    .setErrcode(decrypt.getErrcode())
                    .setCountry(decrypt.getCountry())
                    .setCity(decrypt.getCity())
                    .setAvatarUrl(decrypt.getAvatarUrl())
                    .setErrmsg(decrypt.getErrmsg())
                    .setGender(decrypt.getGender());
            return this;
        }

    }

    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public static class PhoneNumberResult {
        private String phoneNumber;
        private String purePhoneNumber;
        private String countryCode;

        private WechatAppletConfig wechatAppletConfig;

        public PhoneNumberResult analysis(Param param){
            PhoneNumberResult decrypt = AppletUserInfoEntity.decrypt(wechatAppletConfig, param, PhoneNumberResult.class);
            this.setCountryCode(decrypt.getCountryCode())
                    .setPhoneNumber(decrypt.getPhoneNumber())
                    .setPurePhoneNumber(decrypt.getPurePhoneNumber());
            return this;
        }

    }

    public static <T> T decrypt(WechatAppletConfig wechatAppletConfig,Param param,Class<T> clazz){

        if(param.getCode()==null) {
            throw new AppletUserInfoEntityException.NoCodeException("没有Code参数");
        }
        if(param.getEncryptedData()==null){
            throw new AppletUserInfoEntityException.NoEncryptedDataException("没有EncryptedData参数");
        }
        if(param.getIv()==null){
            throw new AppletUserInfoEntityException.NoIvException("没有iv参数");
        }

        AuthCode2SessionEntity.Result aC2SEResult=new AuthCode2SessionEntity.Result().setWechatAppletConfig(wechatAppletConfig)
                .analysis(new AuthCode2SessionEntity.Param().setJs_code(param.getCode()));
        try {
            String decrypt=AesCbcUtil.decrypt(
                    param.getEncryptedData(),
                    aC2SEResult.getSessionKey(),
                    param.getIv(),
                    "UTF-8"
            );
            return JSON.parseObject(decrypt,clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
